/*
 * Main.as
 */

/**
 * @package 
 * @author Dr.NP <np@bsgroup.org>
 * @update 03/18/2013
 * @changelog
 * 		[03/18/2013] - Creation
 */

package 
{
	import flash.display.Sprite;
	import flash.display.StageScaleMode;
	import flash.display.StageAlign;
	import flash.display.GradientType;
	import flash.display.SpreadMethod;
	import flash.display.InterpolationMethod;
	import flash.events.MouseEvent;
	import flash.geom.Matrix;
	import flash.events.Event;
	import fl.controls.*;
	import flash.text.TextFormat;
	import flash.text.TextFormatAlign;
	import flash.text.TextFieldAutoSize;
	import flash.utils.ByteArray;
	
	//import com.adobe.serialization.json.JSON;
	
	import org.bsgroup.bsp.inc.BSPConstants;
	import org.bsgroup.bsp.client.TCPClient;
	import org.bsgroup.bsp.events.BSPEvent;
	import org.bsgroup.bsp.utils.Debugger;
	
	public class Main extends Sprite 
	{
		private const MSG_TYPE_NORMAL : uint = 1;
		private const MSG_TYPE_WARNING : uint = 2;
		private const MSG_TYPE_ERROR : uint = 3;
		
		private var text_addr : TextInput;
		private var text_port : TextInput;
		private var sel_mode : ComboBox;
		private var sel_hb : ComboBox;
		private var btn_connect : Button;
		private var pnl_send : Sprite;
		private var pnl_recv : Sprite;
		private var btn_send : Button;
		private var text_send_cmd : TextInput;
		private var edit_send_input : TextArea;
		private var edit_send_hex : TextArea;
		private var text_recv_cmd : TextInput;
		private var edit_recv_output : TextArea;
		private var edit_recv_hex : TextArea;
		private var status_box : TextInput;
		private var packet_type_grp : RadioButtonGroup;
		
		private var bsp : TCPClient;
		private var n_addr : String;
		private var n_port : uint = 0;
		private var n_mode : uint = 0;
		private var n_hb : int = 0;
		private var n_packet : uint = BSPConstants.PACKET_TYPE_RAW;
		
		public function Main() : void 
		{
			stage.scaleMode = StageScaleMode.NO_SCALE;
			stage.align = StageAlign.TOP_LEFT;
			
			this._init_ui();
			stage.addEventListener(Event.RESIZE, this._resize_ui);
			this._status('Welcome ...');
			
			return;
		}
		
		/* Draw the interface */
		private function _init_ui() : void
		{
			var mtf : TextFormat = new TextFormat();
			mtf.font = 'Arial';
			mtf.size = 22;
			mtf.bold = true;
			mtf.italic = true;
			mtf.color = 0x0d4f82;
			
			var ltf : TextFormat = new TextFormat();
			ltf.font = 'Arial';
			ltf.size = 16;
			ltf.align = TextFormatAlign.LEFT;
			ltf.bold = true;
			
			var ttf : TextFormat = new TextFormat();
			ttf.font = 'Arial';
			ttf.size = 20;
			ttf.color = 0x999999;
			ttf.align = TextFormatAlign.CENTER;
			
			var btf : TextFormat = new TextFormat();
			btf.font = 'Arial';
			btf.size = 14;
			btf.color = 0x666666;
			btf.align = TextFormatAlign.CENTER;
			
			var ntf : TextFormat = new TextFormat();
			ntf.font = 'Courier';
			ntf.size = 12;
			ntf.color = 0x333333;
			ntf.align = TextFormatAlign.LEFT;
			
			var mt : Matrix = new Matrix();
			mt.createGradientBox(150, 50, Math.PI/2, 0, 0);
			this.graphics.beginGradientFill(GradientType.LINEAR, 
					[0x7f7f7f, 0xeeeeee], 
					[100, 100], 
					[0, 255], 
					mt, 
					SpreadMethod.PAD, 
					InterpolationMethod.LINEAR_RGB);
			this.graphics.drawRect(0, 0, 3000, 3000);
			this.graphics.endFill();
			
			// === Title ===
			this.graphics.lineStyle(1, 0x666666, 0.4);
			this.graphics.beginFill(0x789dba, 0.2);
			this.graphics.drawRect(10, 40, 780, 40);
			this.graphics.endFill();
			
			this.text_addr = new TextInput();
			this.text_addr.width = 156;
			this.text_addr.height = 30;
			this.text_addr.x = 64;
			this.text_addr.y = 45;
			this.text_addr.setStyle('textFormat', ttf);
			this.text_addr.setStyle('disabledTextFormat', ttf);
			this.text_addr.text = 'localhost';
			
			this.text_port = new TextInput();
			this.text_port.width = 70;
			this.text_port.height = 30;
			this.text_port.x = 230;
			this.text_port.y = 45;
			this.text_port.maxChars = 5;
			this.text_port.setStyle('textFormat', ttf);
			this.text_port.setStyle('disabledTextFormat', ttf);
			this.text_port.text = '8254';
			
			this.sel_mode = new ComboBox();
			this.sel_mode.width = 100;
			this.sel_mode.height = 30;
			this.sel_mode.x = 360;
			this.sel_mode.y = 45;
			this.sel_mode.textField.setStyle('textFormat', btf);
			this.sel_mode.setStyle('textFormat', btf);
			this.sel_mode.setStyle('disabledTextFormat', btf);
			this.sel_mode.addItem( { label:'PACKET' } );
			this.sel_mode.addItem( { label:'STREAM' } );
			this.sel_mode.addEventListener(Event.CHANGE, function(e : Event) : void {
				return;
			});
			
			this.sel_hb = new ComboBox();
			this.sel_hb.width = 60;
			this.sel_hb.height = 30;
			this.sel_hb.x = 630;
			this.sel_hb.y = 45;
			this.sel_hb.textField.setStyle('textFormat', btf);
			this.sel_hb.setStyle('textFormat', btf);
			this.sel_hb.setStyle('disabledTextFormat', btf);
			this.sel_hb.addItem( { label:'0' } );
			this.sel_hb.addItem( { label:'1' } );
			this.sel_hb.addItem( { label:'2' } );
			this.sel_hb.addItem( { label:'3' } );
			this.sel_hb.addItem( { label:'4' } );
			this.sel_hb.addItem( { label:'5' } );
			this.sel_hb.addItem( { label:'6' } );
			this.sel_hb.addItem( { label:'7' } );
			this.sel_hb.addItem( { label:'8' } );
			this.sel_hb.addItem( { label:'9' } );
			this.sel_hb.addItem( { label:'10' } );
			
			this.btn_connect = new Button();
			this.btn_connect.width = 80;
			this.btn_connect.height = 30;
			this.btn_connect.x = 700;
			this.btn_connect.y = 45;
			this.btn_connect.setStyle('textFormat', btf);
			this.btn_connect.setStyle('disabledTextFormat', btf);
			this.btn_connect.label = 'Connect';
			this.btn_connect.buttonMode = true;
			this.btn_connect.useHandCursor = true;
			this.btn_connect.addEventListener(MouseEvent.CLICK, this._try_connect);
			
			var _lbl_title : Label = new Label();
			_lbl_title.autoSize = TextFieldAutoSize.LEFT;
			_lbl_title.setStyle('textFormat', mtf);
			_lbl_title.text = 'BS.Play protocol debug tool';
			_lbl_title.x = 10;
			_lbl_title.y = 7;
			
			var _lbl_addr : Label = new Label();
			_lbl_addr.setStyle('textFormat', ltf);
			_lbl_addr.text = 'Addr';
			_lbl_addr.x = 20;
			_lbl_addr.y = 50;
			
			var _lbl_port : Label = new Label();
			_lbl_port.setStyle('textFormat', ltf);
			_lbl_port.text = ':';
			_lbl_port.x = 220;
			_lbl_port.y = 50;
			
			var _lbl_mode : Label = new Label();
			_lbl_mode.setStyle('textFormat', ltf);
			_lbl_mode.text = 'Mode';
			_lbl_mode.x = 310;
			_lbl_mode.y = 50;
			
			var _lbl_hb : Label = new Label();
			_lbl_hb.setStyle('textFormat', ltf);
			_lbl_hb.text = 'Heartbeat';
			_lbl_hb.x = 540;
			_lbl_hb.y = 50;
			
			this.status_box = new TextInput();
			this.status_box.enabled = false;
			this.status_box.x = 10;
			this.status_box.y = 570;
			this.status_box.width = 780;
			this.status_box.height = 20;
			
			// === Contents ===
			this.pnl_send = new Sprite();
			this.pnl_send.x = 10;
			this.pnl_send.y = 90;
			this.pnl_recv = new Sprite();
			this.pnl_recv.x = 410;
			this.pnl_recv.y = 90;
			
			var _lbl_send : Label = new Label();
			_lbl_send.autoSize = TextFieldAutoSize.LEFT;
			_lbl_send.setStyle('textFormat', ltf);
			_lbl_send.text = 'Send your data';
			_lbl_send.x = 10;
			_lbl_send.y = 10;
			var _lbl_recv : Label = new Label();
			_lbl_recv.autoSize = TextFieldAutoSize.LEFT;
			_lbl_recv.setStyle('textFormat', ltf);
			_lbl_recv.text = 'Recv from BSP';
			_lbl_recv.x = 10;
			_lbl_recv.y = 10;
			
			var _lbl_cmd : Label = new Label();
			_lbl_cmd.autoSize = TextFieldAutoSize.LEFT;
			_lbl_cmd.setStyle('textFormat', ntf);
			_lbl_cmd.text = "Command :";
			_lbl_cmd.x = 10;
			_lbl_cmd.y = 50;
			
			this.text_send_cmd = new TextInput();
			this.text_send_cmd.setStyle('textFormat', ttf);
			this.text_send_cmd.setStyle('disabledTextFormat', ttf);
			this.text_send_cmd.enabled = false;
			this.text_send_cmd.text = '10000';
			this.text_send_cmd.width = 160;
			this.text_send_cmd.height = 30;
			this.text_send_cmd.x = 80;
			this.text_send_cmd.y = 40;
			
			this.packet_type_grp = new RadioButtonGroup("packet_type");
			this.packet_type_grp.addEventListener(Event.CHANGE, function(e : Event) : void {
				var _rbg : RadioButtonGroup = e.target as RadioButtonGroup;
				n_packet = uint(_rbg.selectedData);
				
				if (n_packet == BSPConstants.PACKET_TYPE_CMD && n_mode == BSPConstants.DATA_TYPE_PACKET)
				{
					text_send_cmd.enabled = true;
				}
				
				else
				{
					text_send_cmd.enabled = false;
				}
			});
			var _rb_raw : RadioButton = new RadioButton();
			_rb_raw.label = "RAW";
			_rb_raw.value = BSPConstants.PACKET_TYPE_RAW;
			_rb_raw.group = this.packet_type_grp;
			_rb_raw.selected = true;
			_rb_raw.x = 150;
			_rb_raw.y = 10;
			
			var _rb_obj : RadioButton = new RadioButton();
			_rb_obj.label = "OBJ";
			_rb_obj.value = BSPConstants.PACKET_TYPE_OBJ;
			_rb_obj.group = this.packet_type_grp;
			_rb_obj.x = 210;
			_rb_obj.y = 10;
			
			var _rb_cmd : RadioButton = new RadioButton();
			_rb_cmd.label = "CMD";
			_rb_cmd.value = BSPConstants.PACKET_TYPE_CMD;
			_rb_cmd.group = this.packet_type_grp;
			_rb_cmd.x = 270;
			_rb_cmd.y = 10;
			
			this.btn_send = new Button();
			this.btn_send.setStyle('textFormat', ltf);
			this.btn_send.setStyle('disabledTextFormat', ltf);
			this.btn_send.label = 'SEND';
			this.btn_send.buttonMode = true;
			this.btn_send.useHandCursor = true;
			this.btn_send.width = 100;
			this.btn_send.height = 30;
			this.btn_send.x = 260;
			this.btn_send.y = 40;
			this.btn_send.enabled = false;
			this.btn_send.addEventListener(MouseEvent.CLICK, this._try_send);
			
			this.edit_send_input = new TextArea();
			this.edit_send_input.setStyle('textFormat', ntf);
			this.edit_send_input.enabled = false;
			this.edit_send_input.height = 190;
			this.edit_send_input.width = 370;
			this.edit_send_input.x = 10;
			this.edit_send_input.y = 80;
			
			this.edit_send_hex = new TextArea();
			this.edit_send_hex.setStyle('textFormat', ntf);
			this.edit_send_hex.textField.opaqueBackground = 0xcccccc;
			this.edit_send_hex.height = 190;
			this.edit_send_hex.width = 370;
			this.edit_send_hex.editable = false;
			this.edit_send_hex.x = 10;
			this.edit_send_hex.y = 280;
			
			this.pnl_send.addChild(_lbl_send);
			this.pnl_send.addChild(_lbl_cmd);
			this.pnl_send.addChild(_rb_raw);
			this.pnl_send.addChild(_rb_obj);
			this.pnl_send.addChild(_rb_cmd);
			this.pnl_send.addChild(this.text_send_cmd);
			this.pnl_send.addChild(this.btn_send);
			this.pnl_send.addChild(this.edit_send_input);
			this.pnl_send.addChild(this.edit_send_hex);
			
			var _lbl_resp : Label = new Label();
			_lbl_resp.autoSize = TextFieldAutoSize.LEFT;
			_lbl_resp.setStyle('textFormat', ntf);
			_lbl_resp.text = "Response :";
			_lbl_resp.x = 10;
			_lbl_resp.y = 50;
			
			this.text_recv_cmd = new TextInput();
			this.text_recv_cmd.setStyle('textFormat', ttf);
			this.text_recv_cmd.editable = false;
			this.text_recv_cmd.width = 160;
			this.text_recv_cmd.height = 30;
			this.text_recv_cmd.x = 80;
			
			this.edit_recv_output = new TextArea();
			this.edit_recv_output.setStyle('textFormat', ntf);
			this.edit_recv_output.editable = false;
			this.edit_recv_output.height = 190;
			this.edit_recv_output.width = 370;
			this.edit_recv_output.x = 10;
			this.edit_recv_output.y = 80;
			
			this.edit_recv_hex = new TextArea();
			this.edit_recv_hex.setStyle('textFormat', ntf);
			this.edit_recv_hex.textField.opaqueBackground = 0xcccccc;
			this.edit_recv_hex.height = 190;
			this.edit_recv_hex.width = 370;
			this.edit_recv_hex.editable = false;
			this.edit_recv_hex.x = 10;
			this.edit_recv_hex.y = 280;
			
			this.text_recv_cmd.y = 40;
			
			this.pnl_recv.addChild(_lbl_recv);
			this.pnl_recv.addChild(_lbl_resp);
			this.pnl_recv.addChild(this.text_recv_cmd);
			this.pnl_recv.addChild(this.edit_recv_output);
			this.pnl_recv.addChild(this.edit_recv_hex);
			
			// === End ===
			this.addChild(_lbl_title);
			this.addChild(_lbl_addr);
			this.addChild(_lbl_port);
			this.addChild(_lbl_mode);
			this.addChild(_lbl_hb);
			
			this.addChild(this.text_addr);
			this.addChild(this.text_port);
			this.addChild(this.sel_mode);
			this.addChild(this.sel_hb);
			this.addChild(this.btn_connect);
			this.addChild(this.status_box);
			
			this.addChild(this.pnl_send);
			this.addChild(this.pnl_recv);
			
			return;
		}
		
		/* Resize stage */
		private function _resize_ui(e : Event) : void
		{
			this.pnl_send.x = 10;
			this.pnl_recv.x = (stage.stageWidth / 2) + 10;
			this.text_send_cmd.width = (stage.stageWidth / 2) - 240;
			this.btn_send.x = (stage.stageWidth / 2) - 140;
			this.edit_send_input.height = (stage.stageHeight - 220) / 2;
			this.edit_send_input.width = (stage.stageWidth / 2) - 30;
			this.edit_send_hex.y = (stage.stageHeight - 200) / 2 + 80;
			this.edit_send_hex.height = (stage.stageHeight - 220) / 2;
			this.edit_send_hex.width = (stage.stageWidth / 2) - 30;
			
			this.text_recv_cmd.width = (stage.stageWidth / 2) - 240;
			this.edit_recv_output.height = (stage.stageHeight - 220) / 2;
			this.edit_recv_output.width = (stage.stageWidth / 2) - 30;
			this.edit_recv_hex.y = (stage.stageHeight - 200) / 2 + 80;
			this.edit_recv_hex.height = (stage.stageHeight - 220) / 2;
			this.edit_recv_hex.width = (stage.stageWidth / 2) - 30;
			
			this.status_box.width = stage.stageWidth - 20;
			this.status_box.y = stage.stageHeight - 30;
			
			return;
		}
		
		/* Output status line */
		private function _status(str : String, type : uint = MSG_TYPE_NORMAL) : void
		{
			var stf : TextFormat = new TextFormat();
			stf.font = 'Arial';
			stf.size = 13;
			switch (type)
			{
				case MSG_TYPE_NORMAL : 
					stf.color = 0x0;
					break;
				case MSG_TYPE_WARNING : 
					stf.color = 0xCC33CC;
					break;
				case MSG_TYPE_ERROR : 
					stf.color = 0xCC3333;
					stf.bold = true;
					break;
				default : 
					break;
			}
			
			this.status_box.setStyle('disabledTextFormat', stf);
			this.status_box.text = str;
			
			return;
		}
		
		private function _try_connect(e : MouseEvent) : void
		{
			if (this.bsp && this.bsp.connected)
			{
				this.bsp.disconnect();
				this.bsp = null;
				this.btn_connect.label = 'Connect';
				this.btn_connect.enabled = true;
				this.text_addr.enabled = true;
				this.text_port.enabled = true;
				this.sel_mode.enabled = true;
				this.sel_hb.enabled = true;
				
				return;
			}
			
			this.n_addr = this.text_addr.text;
			this.n_port = uint(this.text_port.text);
			this.n_mode = (this.sel_mode.selectedIndex == 0) ? BSPConstants.DATA_TYPE_PACKET : BSPConstants.DATA_TYPE_STREAM;
			this.n_hb = int(this.sel_hb.selectedIndex);
			
			this.btn_connect.label = 'Waiting...';
			this.btn_connect.enabled = false;
			this.text_addr.enabled = false;
			this.text_port.enabled = false;
			this.sel_mode.enabled = false;
			this.sel_hb.enabled = false;
			this.bsp = new TCPClient(this.n_addr, this.n_port, this.n_mode, this.n_hb);
			this.bsp.addEventListener(BSPEvent.BSP_CONNECT, this._on_connect);
			this.bsp.addEventListener(BSPEvent.BSP_CLOSE, this._on_close);
			this.bsp.addEventListener(BSPEvent.BSP_IO_ERROR, this._on_io_error);
			this.bsp.addEventListener(BSPEvent.BSP_SEC_ERROR, this._on_sec_error);
			this.bsp.addEventListener(BSPEvent.BSP_STREAM, this._on_data);
			this.bsp.addEventListener(BSPEvent.BSP_PACKET, this._on_packet);
			
			this._status('Connecting to ' + this.n_addr + ':' + this.n_port + ' ...', MSG_TYPE_WARNING);
			
			this.bsp.connect();
			
			return;
		}
		
		private function _try_send(e : MouseEvent) : void
		{
			var stream : ByteArray;
			var raw : ByteArray;
			if (this.n_mode == BSPConstants.DATA_TYPE_PACKET)
			{
				// Packet mode, parse JSON string into object
				if (!this.edit_send_input.text)
				{
					this._status('No data to send', MSG_TYPE_WARNING);
					return;
				}
				
				if (this.n_packet == BSPConstants.PACKET_TYPE_CMD && !this.text_send_cmd.text)
				{
					this._status('No command ID', MSG_TYPE_WARNING);
					return;
				}
				
				if (this.n_packet == BSPConstants.PACKET_TYPE_RAW)
				{
					// Just send raw data
					raw = new ByteArray();
					raw.writeUTFBytes(this.edit_send_input.text);
					stream = this.bsp.send_raw(raw);
					if (stream)
					{
						this._status('Try sending ' + stream.length + ' bytes to server');
						this.edit_send_hex.text = Debugger.trace_hex(stream);
					}
					
					else
					{
						this._status('Send error', MSG_TYPE_ERROR);
					}
					return;
				}
				
				try
				{
					var send_obj : * = JSON.parse(this.edit_send_input.text);
					this._status('Input parsed as ' + typeof(send_obj));
					if (typeof(send_obj) == 'object')
					{
						// Try send
						if (this.n_packet == BSPConstants.PACKET_TYPE_CMD)
						{
							stream = this.bsp.send_cmd(int(this.text_send_cmd.text), send_obj);
						}
						
						else
						{
							stream = this.bsp.send_obj(send_obj);
						}
						
						if (stream)
						{
							this._status('Try sending ' + stream.length + ' bytes to server');
							this.edit_send_hex.text = Debugger.trace_hex(stream);
						}
						
						else
						{
							this._status('Send error', MSG_TYPE_ERROR);
						}
						return;
					}
					
					else
					{
						this._status('Input parse as ' + typeof(send_obj) + ', cannot send in PACKET mode');
					}
				}
				
				catch (e : * )
				{
					this._status('Invalid input data', MSG_TYPE_ERROR);
					return;
				}
			}
			
			else
			{
				// RAW stream, ignore command
				if (!this.edit_send_input)
				{
					this._status('No data to send', MSG_TYPE_WARNING);
					return;
				}
				
				raw = new ByteArray();
				raw.writeUTFBytes(this.edit_send_input.text);
				stream = this.bsp.send_stream(raw);
				
				if (stream)
				{
					this._status('Try sending ' + stream.length + ' bytes to server');
					this.edit_send_hex.text = Debugger.trace_hex(stream);
				}
				
				else
				{
					this._status('Send error', MSG_TYPE_ERROR);
				}
			}
			
			return;
		}
		
		private function _on_connect(e : BSPEvent) : void
		{
			this.btn_connect.label = 'Disconnect';
			this.btn_connect.enabled = true;
			this.btn_send.enabled = true;
			this.edit_send_input.enabled = true;
			
			this._status('Connected.');
			
			return;
		}
		
		private function _on_close(e : BSPEvent) : void
		{
			this.btn_connect.label = 'Connect';
			this.btn_connect.enabled = true;
			this.text_addr.enabled = true;
			this.text_port.enabled = true;
			this.sel_mode.enabled = true;
			this.sel_hb.enabled = true;
			this.btn_send.enabled = false;
			this.edit_send_input.enabled = false;
			this.text_send_cmd.enabled = false;
			this._status('Connection closed');
			
			return;
		}
		
		private function _on_data(e : BSPEvent) : void
		{
			this._status('Recieve data from BSP server');
			
			return;
		}
		
		private function _on_packet(e : BSPEvent) : void
		{
			var pkg : Object;
			var res : Object
			while (pkg = this.bsp.get_packet())
			{
				this._status('Get a packet type ' + pkg.type + ' from server');
				// Get the last;
				res = pkg;
			}
			
			// Fill text
			switch (res.type)
			{
				case BSPConstants.PACKET_TYPE_RAW : 
					this.text_recv_cmd.text = '';
					this.edit_recv_output.text = Debugger.dump_bytearray(res.raw);
					break;
				case BSPConstants.PACKET_TYPE_OBJ : 
					this.text_recv_cmd.text = '';
					this.edit_recv_output.text = Debugger.dump_object(res.obj);
					break;
				case BSPConstants.PACKET_TYPE_CMD : 
					this.text_recv_cmd.text = res.cmd;
					this.edit_recv_output.text = Debugger.dump_object(res.params);
					break;
				default : 
					break;
			}
			
			this.edit_recv_hex.text = Debugger.trace_hex(res.stream);
			
			return;
		}
		
		private function _on_io_error(e : BSPEvent) : void
		{
			if (this.bsp)
			{
				this.bsp.disconnect();
				this.bsp = null;
			}
			
			this.btn_connect.label = 'Connect';
			this.btn_connect.enabled = true;
			this.text_addr.enabled = true;
			this.text_port.enabled = true;
			this.sel_mode.enabled = true;
			this.sel_hb.enabled = true;
			this.btn_send.enabled = false;
			this.edit_send_input.enabled = false;
			this.text_send_cmd.enabled = false;
			this._status('Network IO error, check your connection please.', MSG_TYPE_ERROR);
			
			return;
		}
		
		private function _on_sec_error(e : BSPEvent) : void
		{
			if (this.bsp)
			{
				this.bsp.disconnect();
				this.bsp = null;
			}
			
			this.btn_connect.label = 'Connect';
			this.btn_connect.enabled = true;
			this.text_addr.enabled = true;
			this.text_port.enabled = true;
			this.sel_mode.enabled = true;
			this.sel_hb.enabled = true;
			this.btn_send.enabled = false;
			this.edit_send_input.enabled = false;
			this.text_send_cmd.enabled = false;
			this._status('Security sandbox error.', MSG_TYPE_ERROR);
			
			return;
		}
	}
}